package cn.stylefeng.guns.modular.business.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import cn.stylefeng.guns.core.exception.BusinessException;
import cn.stylefeng.guns.modular.business.entity.SampleData;
import cn.stylefeng.guns.modular.business.entity.SampleStorageLocation;
import cn.stylefeng.guns.modular.business.exception.SampleExceptionEnum;
import cn.stylefeng.guns.modular.business.mapper.SampleDataMapper;
import cn.stylefeng.guns.modular.business.reqeust.SampleDataRequest;
import cn.stylefeng.guns.modular.business.service.ISampleDataService;
import cn.stylefeng.guns.modular.business.service.ISampleStorageLocationService;
import cn.stylefeng.roses.kernel.auth.api.context.LoginContext;
import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
import cn.stylefeng.roses.kernel.config.api.context.ConfigContext;
import cn.stylefeng.roses.kernel.db.api.factory.PageFactory;
import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author generator
 * @since 2024-07-11
 */
@Service
public class SampleDataServiceImpl extends ServiceImpl<SampleDataMapper, SampleData> implements ISampleDataService {

    @Autowired
    private ISampleStorageLocationService sampleStorageLocationService;
    @Override
    public PageResult<SampleData> findPage(SampleDataRequest sampleDataRequest) {
        LambdaQueryWrapper<SampleData> wrapper = createWrapper(sampleDataRequest);
        Page<SampleData> page = this.page(PageFactory.defaultPage(), wrapper);
        if(CollUtil.isNotEmpty(page.getRecords())){
            String host = ConfigContext.me().getConfigValue("SYS_SERVER_DEPLOY_HOST", String.class);
            String apiPath = "/api";
            if(host.contains(apiPath))  {
                host =host.replace(apiPath, "/viewQr/");
            }
            String finalHost = host;
            page.getRecords().forEach(sampleData -> {
                // 处理你的数据
                String url = finalHost + sampleData.getId();
                String str1 = "Name:"+sampleData.getName();
                String str2 = "Date:"+sampleData.getDate();
                String str3 = "Keywords:"+sampleData.getSamplesKeywords();
                BufferedImage image = mergeImagesVertically(QrCodeUtil.generate(//
                        url, //二维码内容
                        QrConfig.create()
                ), createImageFromText(str1, str2, str3));
                sampleData.setQrBase64(convertBufferedImageToBase64(image));
            });
        }
        return PageResultFactory.createPageResult(page);
    }

    @Override
    @Transactional
    public void removeByIdExt(Long id) {
        LoginUser loginUser = LoginContext.me().getLoginUser();
        SampleData sampleData = this.getById(id);
        if(sampleData == null){
            throw new BusinessException(SampleExceptionEnum.SAMPLE_NULL_ERROR);
        }
        if(!LoginContext.me().getSuperAdminFlag() && !loginUser.getUserId().equals(sampleData.getCreateUser())){
            throw new BusinessException(SampleExceptionEnum.SAMPLE_DELETE_ERROR);
        }
        this.removeById(id);
        sampleStorageLocationService.remove(Wrappers.<SampleStorageLocation>lambdaQuery().eq(SampleStorageLocation::getSampleDataId,id));
    }

    @Override
    public SampleData getByIdExt(Long id) {
        SampleData sampleData = this.getById(id);
        if(sampleData == null){
            throw new BusinessException(SampleExceptionEnum.SAMPLE_NULL_ERROR);
        }
        List<SampleStorageLocation> list = sampleStorageLocationService.list(Wrappers.<SampleStorageLocation>lambdaQuery().eq(SampleStorageLocation::getSampleDataId, id));
        sampleData.setStorageLocationList(list);
        return sampleData;
    }

    @Override
    public void saveExt(SampleData sampleData) {
        this.save(sampleData);
        List<SampleStorageLocation> storageLocationList = sampleData.getStorageLocationList();
        if(CollUtil.isNotEmpty(storageLocationList)){
            sampleStorageLocationService.saveBatch(storageLocationList);
        }
    }

    @Override
    public void updateByIdExt(SampleData sampleData) {
        this.updateById(sampleData);
        List<SampleStorageLocation> storageLocationList = sampleData.getStorageLocationList();
        if(CollUtil.isNotEmpty(storageLocationList)){
            sampleStorageLocationService.saveOrUpdateBatch(storageLocationList);
        }
    }

    public static String convertBufferedImageToBase64(BufferedImage image) {
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            // 将 BufferedImage 写入 ByteArrayOutputStream
            ImageIO.write(image, "png", outputStream);
            byte[] imageBytes = outputStream.toByteArray();

            // 将字节数组编码为 Base64 字符串
            String base64String = Base64.getEncoder().encodeToString(imageBytes);
            return "data:image/png;base64," + base64String;
        } catch (IOException e) {
            throw new RuntimeException("Failed to convert image to Base64", e);
        }
    }


    public static BufferedImage mergeImagesVertically(BufferedImage img1, BufferedImage img2) {
        // 获取两张图片的宽度和高度
        int width = Math.max(img1.getWidth(), img2.getWidth());
        int height1 = img1.getHeight();
        int height2 = img2.getHeight();

        // 创建一个新的 BufferedImage，其宽度是两张图片中的最大值，高度是两张图片高度之和
        int mergedWidth = width;
        int mergedHeight = height1 + height2;
        BufferedImage mergedImage = new BufferedImage(mergedWidth, mergedHeight, BufferedImage.TYPE_INT_RGB);

        // 获取 Graphics2D 对象
        Graphics2D g2d = mergedImage.createGraphics();

        // 设置背景颜色并清空整个画布
        g2d.setColor(Color.WHITE); // 设置白色背景
        g2d.fillRect(0, 0, mergedWidth, mergedHeight);

        // 绘制第一张图片
        g2d.drawImage(img1, 0, 0, null);

        // 绘制第二张图片
        g2d.drawImage(img2, 0, height1, null);

        // 释放 Graphics2D 对象
        g2d.dispose();

        return mergedImage;
    }
    public static BufferedImage createImageFromText(String... lines) {
        // 定义图像的宽度和高度
        int width = 300;
        int lineHeight = 25;  // 每行的高度
        int height = lines.length * lineHeight;  // 根据行数计算总高度

        // 创建一个 BufferedImage 对象
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        // 获取图形上下文
        Graphics2D g2d = bufferedImage.createGraphics();

        // 设置抗锯齿
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // 设置背景颜色并清空整个画布
        g2d.setColor(Color.WHITE);
        g2d.fillRect(0, 0, width, height);

        // 设置文本颜色和字体
        g2d.setColor(Color.BLACK);
        g2d.setFont(new Font("Arial", Font.BOLD, 30));

        // 绘制每行文本
        for (int i = 0; i < lines.length; i++) {
            String line = lines[i];
            int textWidth = g2d.getFontMetrics().stringWidth(line);
            int x = (width - textWidth) / 2;
            int y = lineHeight * i + g2d.getFontMetrics().getAscent() + (lineHeight - g2d.getFontMetrics().getHeight()) / 2;
            g2d.drawString(line, x, y);
        }

        // 释放图形上下文
        g2d.dispose();

        // 返回生成的 BufferedImage
        return bufferedImage;
    }
    // 方法1：从文本创建 BufferedImage
    public static BufferedImage createImageFromText(String text) {
        // 定义图像的宽度和高度
        int width = 300;
        int height = 100;

        // 创建一个 BufferedImage 对象
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        // 获取图形上下文
        Graphics2D g2d = bufferedImage.createGraphics();

        // 设置抗锯齿
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // 设置背景颜色并清空整个画布
        g2d.setColor(Color.WHITE);
        g2d.fillRect(0, 0, width, height);

        // 设置文本颜色和字体
        g2d.setColor(Color.BLACK);
        g2d.setFont(new Font("Arial", Font.BOLD, 24));

        // 计算文本位置以便居中显示
        int textWidth = g2d.getFontMetrics().stringWidth(text);
        int x = (width - textWidth) / 2;
        int y = (height - g2d.getFontMetrics().getHeight()) / 2 + g2d.getFontMetrics().getAscent();

        // 绘制文本
        g2d.drawString(text, x, y);

        // 释放图形上下文
        g2d.dispose();

        // 返回生成的 BufferedImage
        return bufferedImage;
    }
    private LambdaQueryWrapper<SampleData> createWrapper(SampleDataRequest sampleDataRequest) {
        LambdaQueryWrapper<SampleData> queryWrapper = new LambdaQueryWrapper<>();
        // 查询未删除状态的
        //queryWrapper.eq(SampleData::getDelFlag, SysEnum.NO.getCode());

        // SQL条件拼接
        queryWrapper.like(StrUtil.isNotEmpty(sampleDataRequest.getSearchText()), SampleData::getName, sampleDataRequest.getSearchText());

        // 根据创建时间降序排列
        //queryWrapper.orderByDesc(SampleData::getCreateTime);
        return queryWrapper;
    }
}
